package com.zeng.createmd.restfulmodule.util;

import com.zeng.createmd.restfulmodule.itemCache.ItemCache;
import com.zeng.createmd.servicemodule.vo.DatabaseVo;
import com.zeng.createmd.servicemodule.vo.ItemVo;
import com.zeng.plugin.entity.MenuView;
import com.zeng.plugin.util.HumpStringUtil;
import org.apache.commons.io.IOUtils;
import org.apache.ibatis.jdbc.ScriptRunner;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.*;
import java.util.stream.Collectors;

public class InitDatabaseDataUtil {

    public static void initData(DatabaseVo databaseVo) throws IOException, SQLException {
        Connection connection = null;
        InputStreamReader inputStreamReader = null;
        InputStream resourceAsStream = null;

        try {
            connection = JDBCUtil.getConnection(databaseVo);
            resourceAsStream = InitDatabaseDataUtil.class.getClassLoader().getResourceAsStream("sql/data.sql");
            inputStreamReader = new InputStreamReader(resourceAsStream, "UTF-8");

            ScriptRunner scriptRunner = new ScriptRunner(connection);
            scriptRunner.runScript(inputStreamReader);
            scriptRunner.closeConnection();
        } finally {
            if (connection != null) {
                connection.close();
            }
            CloseUtil.close(inputStreamReader, resourceAsStream);
        }
    }

    public static void initDataForMenu(DatabaseVo databaseVo) throws SQLException {
        List<Map<String, Map<String, String>>> maps = handleMenuView();
        if (maps == null) {
            return;
        }
        StringBuilder head = new StringBuilder("INSERT INTO `sys_permission`(`code`, `insert_date`, `update_date`, `valid`, `version`, `available`, `name`, `parent_code`, `parent_codes`, `per_config`, `sort_string`, `type`, `url`) VALUES ");

        String sqlTemplate = "(%s, NOW(), NOW(), 1, 0, 1, %s, %s, NULL, '{}', NULL, 'menu', %s),";
        Map<String, String> oneMenuAndUUID = new HashMap<>();
        for (Map<String, Map<String, String>> map : maps) {
            for (String s : map.keySet()) {
                Map<String, String> stringStringMap = map.get(s);
                if (oneMenuAndUUID.get(s) == null) {
                    String uuid = UUID.randomUUID().toString().replace("-", "");
                    oneMenuAndUUID.put(s, uuid);
                    head.append(String.format(sqlTemplate, "'" + oneMenuAndUUID.get(s) + "'", "'" + s + "'", null, null));
                }
                for (String s1 : stringStringMap.keySet()) {
                    head.append(String.format(sqlTemplate, "REPLACE(UUID(),'-','')", "'" + s1 + "'", "'" + oneMenuAndUUID.get(s) + "'", "'/" + StringUtil.uncapFirst(stringStringMap.get(s1)) + "/list'"));
                }
            }
        }
        head.setCharAt(head.length() - 1, ' ');
        Connection connection = null;
        try {
            connection = JDBCUtil.getConnection(databaseVo);
            JDBCUtil.executeSql(connection, head.toString());
        } finally {
            if (connection != null) {
                connection.close();
            }
        }
    }

    private static List<Map<String, Map<String, String>>> handleMenuView() {
        ProjectUtil projectUtil = new ProjectUtil();
        Map<String, MenuView> menuView = (Map<String, MenuView>) projectUtil.getData().get("menuView");
        if (menuView == null) {
            return null;
        }
        Collection<MenuView> values = menuView.values();
        if (values == null || values.size() <= 0) {
            return null;
        }
        List<Map<String, Map<String, String>>> oneMenuToTowMenuTableName = new ArrayList<>();
        for (MenuView value : values) {
            String twoLevelMenu = value.getTwoLevelMenu();
            String oneLevelMenu = value.getOneLevelMenu();
            String tableName = value.getTableName();
            Map<String, String> map = new HashMap<>();
            map.put(twoLevelMenu, tableName);
            Map<String, Map<String, String>> oneMenuAndTwoMenuTableNameMap = new HashMap<>();
            oneMenuAndTwoMenuTableNameMap.put(oneLevelMenu, map);
            oneMenuToTowMenuTableName.add(oneMenuAndTwoMenuTableNameMap);
        }
        return oneMenuToTowMenuTableName;

    }

}
